# -*- coding: utf-8 -*-

import wx
import MySQLdb

from MyGrid import MyGrid
from wx.grid import EVT_GRID_LABEL_LEFT_DCLICK, EVT_GRID_CELL_RIGHT_CLICK
from wx._core import EVT_BUTTON, EVT_COMBOBOX, EVT_KEY_DOWN, WXK_UP, WXK_DOWN
from wx._controls import EVT_TEXT_ENTER

import DBEvents
from GlobalVars import global_settings
from DialogCollection import DialogCollection
from BFCursor import BFCursor

class DBManagerFrame(wx.Frame):
    def __init__(self, connection, userHistory, *args, **kwds):
        kwds["style"] = wx.DEFAULT_FRAME_STYLE
        wx.Frame.__init__(self, *args, **kwds)
        #prepare history
        self.history, self.historyPos = userHistory, len(userHistory) - 1
        #prepare connection
        self.connection = connection[0]
        self.cursor = self.connection.cursor(BFCursor) #self.connection.cursor() MySQLdb.cursors.DictCursor)
        self.activeUser = connection[1]
        self.activeBase = None
        self.activeTable = None
        #any GUI objects
        self.executeButton = wx.Button(self, -1, u"выполнить")
        self.commandTextCtrl = wx.TextCtrl(self, -1, "", style=wx.TE_PROCESS_ENTER )
        self.labelStatusRequest = wx.StaticText(self, -1, " ", style=wx.ALIGN_CENTER_HORIZONTAL)
        self.static_line_1 = wx.StaticLine(self, -1)
        bases = self.cursor.execGetDatabases(); 
        #bases = self.getOnlyValues(bases);
        self.combo_box_1 = wx.ComboBox(self, -1, choices=bases, style=wx.CB_DROPDOWN|wx.CB_READONLY)
        self.treeCtrl = wx.TreeCtrl(self, -1, style=wx.TR_HAS_BUTTONS|wx.TR_NO_LINES|wx.TR_DEFAULT_STYLE|wx.SUNKEN_BORDER|wx.TR_HIDE_ROOT)
        self.static_line_2 = wx.StaticLine(self, -1, style=wx.LI_VERTICAL)
        self.dc = wx.WindowDC(self)
        self.dc.SetFont(self.GetFont())
        #init dialog's manager
        self.dialogCollection = DialogCollection(self.cursor)
        #menu initialization
            #file
        self.file = wx.Menu()
        dont_push = self.file.Append(-1, "Не нажимать!","тестовая кнопка")
        
        self.file.AppendSeparator()
        logout = self.file.Append(-1, "Logout", "Selecting this item will exit the program")
        self.Bind(wx.EVT_MENU, lambda event: wx.MessageBox("как легко манипулировать людьми... :-)"), dont_push)
        self.Bind(wx.EVT_MENU, self.onLogout, logout)
            #edit
        self.settings = wx.Menu()
        needToFormat = self.settings.AppendCheckItem(-1, "форматировать вывод")
        self.Bind(wx.EVT_MENU, lambda event: self.changeSettings("gridFormat"), needToFormat)
            #adding to menuBar
        menuBar = wx.MenuBar()
        menuBar.Append(self.file, "File")
        menuBar.Append(self.settings, "Settings")
        self.SetMenuBar(menuBar)
        
        self.toolbar = self.CreateToolBar(wx.TB_HORIZONTAL|wx.NO_BORDER)
        self.ToolBar = self.toolbar
        self.toolbar.SetToolBitmapSize((21,21))

        self.CREATE_BASE_ID, self.CREATE_TABLE_ID, self.SEARCH_ID, self.INSERT_INTO_TABLE = wx.NewId(), wx.NewId(), wx.NewId(), wx.NewId()
        self.toolbar.AddLabelTool(self.CREATE_BASE_ID, '', wx.Bitmap('../icons/new-base.png'), shortHelp='Создать новую бд')
        self.toolbar.AddLabelTool(self.CREATE_TABLE_ID, '', wx.Bitmap('../icons/new-table.png'), shortHelp='Создать новую таблицу в текущей бд')
        self.toolbar.AddSeparator()
        self.toolbar.AddLabelTool(self.SEARCH_ID, '', wx.Bitmap('../icons/search24.png'), shortHelp='что-нибудь найти')
        self.toolbar.AddLabelTool(self.INSERT_INTO_TABLE, '', wx.Bitmap('../icons/contact-new.png'), shortHelp='добавить значение в текущую таблицу')
        self.toolbar.Realize()

        self.grid_1 = MyGrid(self, self.dc, [])
        self.static_line_3 = wx.StaticLine(self, -1)
        self.label_1 = wx.StaticText(self, -1, u"пользователь - " + str(self.activeUser), style=wx.ALIGN_CENTRE)
        self.logoutButton = wx.Button(self, -1, u"Выйти")

        self.__set_properties()
        self.__do_layout()
        self.__bind_controls()
        
        #import settings
        if global_settings['gridFormat']: needToFormat.Toggle()

    def __set_properties(self):
        self.SetTitle("BaseFace")
        self.SetSize((800, 600))
        self.SetBackgroundColour(wx.Colour(236, 233, 228))
        self.SetFont(wx.Font(11, wx.DEFAULT, wx.NORMAL, wx.NORMAL, 0, "Ubuntu"))
        self.grid_1.EnableEditing(0)
        
    def __do_layout(self):
        sizer_1 = wx.BoxSizer(wx.VERTICAL)
        sizer_7 = wx.BoxSizer(wx.HORIZONTAL)
        sizer_2 = wx.BoxSizer(wx.HORIZONTAL)
        sizer_5 = wx.BoxSizer(wx.VERTICAL)
        sizer_6 = wx.BoxSizer(wx.HORIZONTAL)
        sizer_3 = wx.BoxSizer(wx.HORIZONTAL)
        sizer_3.Add(self.executeButton, 1, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 2)
        sizer_3.Add(self.commandTextCtrl, 3, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 2)
        sizer_1.Add(sizer_3, 1, wx.ALL|wx.EXPAND, 2)
        sizer_1.Add(self.labelStatusRequest, 0, wx.ALIGN_CENTER_HORIZONTAL, 2)
        sizer_1.Add(self.static_line_1, 0, wx.ALL|wx.EXPAND, 3)
        sizer_6.Add(self.combo_box_1, 0, 0, 0)
        sizer_5.Add(sizer_6, 1, wx.ALL|wx.EXPAND, 2)
        sizer_5.Add(self.treeCtrl, 14, wx.ALL|wx.EXPAND, 2)
        sizer_2.Add(sizer_5, 1, wx.ALL|wx.EXPAND, 2)
        sizer_2.Add(self.static_line_2, 0, wx.ALL|wx.EXPAND, 3)
        sizer_2.Add(self.grid_1, 3, wx.ALL|wx.EXPAND, 2)
        sizer_1.Add(sizer_2, 12, wx.ALL|wx.EXPAND, 3)
        sizer_1.Add(self.static_line_3, 0, wx.ALL|wx.EXPAND, 3)
        sizer_7.Add(self.label_1, 5, wx.ALL|wx.ALIGN_CENTER_VERTICAL, 2)
        sizer_7.Add(self.logoutButton, 1, wx.EXPAND, 2)
        sizer_1.Add(sizer_7, 1, wx.ALL|wx.EXPAND, 2)
        self.SetSizer(sizer_1)
        self.Layout()

    def __bind_controls(self):
        self.Bind(EVT_BUTTON, self.onLogout, self.logoutButton)
        self.Bind(EVT_BUTTON, self.onExecute, self.executeButton)
        self.Bind(EVT_TEXT_ENTER, self.onExecute, self.commandTextCtrl)
        self.commandTextCtrl.Bind(EVT_KEY_DOWN, self.onKeyPressed, self.commandTextCtrl)
        self.Bind(EVT_COMBOBOX, self.setActiveBase, self.combo_box_1)
        self.Bind(wx.EVT_TOOL, self.onCreateBase, id=self.CREATE_BASE_ID)
        self.Bind(wx.EVT_TOOL, self.onCreateTable, id=self.CREATE_TABLE_ID)
        self.Bind(wx.EVT_TOOL, self.onSearchDialog, id=self.SEARCH_ID)
        self.Bind(wx.EVT_TOOL, self.onInsertIntoTable, id=self.INSERT_INTO_TABLE)
        self.Bind(EVT_GRID_LABEL_LEFT_DCLICK, self.onLabelLeftDClick, self.grid_1)
        self.Bind(EVT_GRID_CELL_RIGHT_CLICK, self.onCellRightClick, self.grid_1)

    def onCreateBase(self, event):
        self.dialogCollection.onCreateBase()
        self.combo_box_1.SetItems(self.cursor.execGetDatabases())

    def onCreateTable(self, event):
        print self.activeTable
        if self.activeBase != None:
            self.dialogCollection.onCreateTable()
            self.initTree() 
        else:
            message = wx.MessageDialog(None, u"база не выбрана", u"Message", wx.ICON_INFORMATION)
            message.ShowModal()
            message.Destroy()
        print self.activeTable
        
    def onSearchDialog(self, event):
        selected = self.grid_1.GetSelectedCols()
        if len(selected) == 0:
            message = wx.MessageDialog(None, u"Выберете один или несколько столбцов\n(один клик по заголовку)", u"Message", wx.ICON_INFORMATION)
            message.ShowModal()
            message.Destroy()
        else:
            selected.sort()
            columns = self.cursor.getColumnLabels()
            self.dialogCollection.onSearch(self.activeTable, [columns[i] for i in selected], self.grid_1)
    
    def onLabelLeftDClick(self, event):
        column = self.cursor.getColumnLabels()[event.GetCol()]
        dialog = wx.TextEntryDialog(None,"введите искомое значение", "быстрый поиск по "+ column, "", style=wx.OK)
        if dialog.ShowModal() == wx.ID_OK:
            command = "select * from " + self.activeTable + " where " + column + " like '%" + dialog.GetValue() + "%'"
            self.sendRequestAndDraw(command)
            dialog.Destroy()
    
    def onCellRightClick(self, event):
        pass
    
    def onInsertIntoTable(self, event):
        if self.activeTable != None:
            self.dialogCollection.onInsertIntoTable(self.activeTable)
        else:
            message = wx.MessageDialog(None, u"таблица не выбрана", u"Message", wx.ICON_INFORMATION)
            message.ShowModal()
            message.Destroy()

    def changeSettings(self, key):
        global_settings[key] = not global_settings[key]
        
    def initTree(self):
        self.treeCtrl.DeleteAllItems()
        root = self.treeCtrl.AddRoot(self.activeBase)
        tables = self.cursor.execGetTables()
        for table in tables:
            self.treeCtrl.AppendItem(root, table) 
        self.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.onActivated, self.treeCtrl)
        
    def onActivated(self, event):
        label = self.treeCtrl.GetItemText(event.GetItem())
        self.activeTable = label
        data = self.cursor.execGetAllFrom(label)
        self.changeGrid(data) 
        
    def AddTreeNodes(self, parentItem, items):
        for item in items:
            if type(item[0]) == str:
                self.treeCtrl.AppendItem(parentItem, item[0])
            else:
                newItem = self.treeCtrl.AppendItem(parentItem, item[0][0])
                self.AddTreeNodes(newItem, item[0][1])
                
    def onLogout(self, event):
        evt = DBEvents.LogoutEvent(DBEvents.myEVT_USER_LOGOUT, self.GetId())
        self.GetEventHandler().ProcessEvent(evt)
         
    def onExecute(self, event):
        command = self.commandTextCtrl.GetValue()
        if len(command) > 0:
            self.history.insert(len(self.history) - 1,command)
            self.historyPos = len(self.history) - 1
            self.commandTextCtrl.SetValue('')
            try:
                data = self.cursor.sendRequest(command)
                if len(data) > 0:
                    self.changeGrid(data)
                self.labelStatusRequest.SetLabel("ok")
            except MySQLdb.Error:
                    self.labelStatusRequest.SetLabel(str("error"))
                    
    def onKeyPressed(self, event):
        if event.GetKeyCode() == WXK_UP:
            if self.historyPos > 0:
                self.historyPos = self.historyPos - 1
            self.commandTextCtrl.SetValue(self.history[self.historyPos])
        if event.GetKeyCode() == WXK_DOWN:
            if self.historyPos < len(self.history) - 1:
                self.historyPos = self.historyPos + 1
            self.commandTextCtrl.SetValue(self.history[self.historyPos])
        event.Skip() 
        
    def setActiveBase(self, event):
        self.cursor.execSelectDb(event.String)
        self.activeBase = event.String
        self.initTree()
        
    def changeGrid(self, data, rowLabels=None, colLabels=None):
        columns = self.cursor.getColumnLabels()
        self.grid_1.setData(data, colLabels=columns)
        self.grid_1.Refresh()

    def sendRequestAndDraw(self, command):
        self.changeGrid(self.cursor.sendRequest(command))
        